package beautiful.butterfly.drds.binlog.parser;


import beautiful.butterfly.drds.binlog.connection.ConnectionAttributes;
import beautiful.butterfly.drds.binlog.event.EventData;
import beautiful.butterfly.drds.binlog.event.data.QueryEventData;
import beautiful.butterfly.drds.binlog.netty.server.NioSocketChannelExtend;
import beautiful.butterfly.drds.binlog.utils.ByteUtils;
import beautiful.butterfly.drds.binlog.utils.SqlUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class QueryEventDataParser implements EventDataParser
{


    @Override
    public EventData parse(ByteBuf msg, ChannelHandlerContext context, int checksumLength) throws Exception
    {
        // TODO Auto-generated method stub
        // LoggerUtils.debug(logger, "enter QueryEventDataParser.parse(...)");
        long threadId = ByteUtils.readUnsignedLong(msg, 4);
        long executeTime = ByteUtils.readUnsignedLong(msg, 4);
        msg.skipBytes(1);// 忽略1个字节
        int errorCode = ByteUtils.readUnsignedInt(msg, 2);
        msg.skipBytes(ByteUtils.readUnsignedInt(msg, 2));
        String database = ByteUtils.readZeroTerminatedString(msg);
        String sql = ByteUtils.readSpecifiedLengthString(msg,
                ByteUtils.availableWithChecksumLength(msg, checksumLength));
        QueryEventData eventData = new QueryEventData();
        eventData.setThreadId(threadId);
        eventData.setExecuteTime(executeTime);
        eventData.setErrorCode(errorCode);
        eventData.setDatabase(database);
        eventData.setSql(sql);
        // 0)创建表,不强拉，留到产生数据时来做
        // 1) 修改表结构，需要强制拉取数据
        if (SqlUtils.isAlterTableSql(sql))
        {
            String table = SqlUtils.getTableNameBySqlParser(sql);
            log.info("altered tableName name is :" + table + " sql:" + sql);
            if (null != table && table.length() > 0)
            {
                ConnectionAttributes connectionAttributes = ((NioSocketChannelExtend) context.channel()).getConnectionAttributes();
                // 加上判断，需要的表，我们才会去获取，否则置之不理
                if (connectionAttributes.acceptByFilter(database, table))
                {
                    connectionAttributes.ensureDatabaseTableColumnsMappingExist(database, table, true);// 强制更新
                }
            } else
            {
                log.info("fail to get tableName name by alter sql:" + sql);
                throw new Exception("fail to get talbe name by alter sql:" + sql);
            }
        } else if (SqlUtils.isDropTableSql(sql))
        {
            String table = SqlUtils.getTableNameBySqlParser(sql);
            log.info("dropped tableName name is :" + table + " sql:" + sql);
            if (null != table && table.length() > 0)
            {// 强制删除此表的映射关系
                ConnectionAttributes connectionAttributes = ((NioSocketChannelExtend) context.channel()).getConnectionAttributes();
                connectionAttributes.ensureDatabaseTableColumnsMappingDeleted(database, table);
            } else
            {
                log.info("fail to get tableName name by alter sql:" + sql);
                throw new Exception("fail to get talbe name by drop sql:" + sql);
            }
        }
        return eventData;
    }

}
